package cn.com;

import java.util.Enumeration;

import javax.servlet.http.HttpServletRequest;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.HttpMethod;
import org.springframework.http.HttpStatus;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.oauth2.config.annotation.web.configuration.EnableResourceServer;
import org.springframework.security.oauth2.config.annotation.web.configuration.ResourceServerConfigurerAdapter;
import org.springframework.security.oauth2.config.annotation.web.configurers.ResourceServerSecurityConfigurer;
import org.springframework.security.oauth2.provider.token.RemoteTokenServices;
import org.springframework.util.MultiValueMap;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseStatus;
import org.springframework.web.bind.annotation.RestController;

import cn.com.util.HttpUtil;

import com.google.gson.JsonObject;
import com.google.gson.JsonParser;

/**
 * to use remote oauth server to authentication token
 */
@SpringBootApplication
@Configuration
@EnableResourceServer
@RestController
public class RemoteResourceApplication extends ResourceServerConfigurerAdapter {


	
	String scope = "read";//授权类型
	String username = "admin";//登陆账号
	String serverUrl = "http://localhost:9008";//认证服务器
	String clientUrl = "http://localhost:9009";//客户端
	String publicResource = "/public";//公开资源
	String authResource = "/protect";//授权资源
	
    /**
     * 方式一：调用远程Auth server进行token校验
     * @return
     */
    @Bean
    public RemoteTokenServices remoteTokenServices() {
        RemoteTokenServices remoteTokenServices = new RemoteTokenServices();
        remoteTokenServices.setCheckTokenEndpointUrl(serverUrl+"/oauth/check_token");
        return remoteTokenServices;
    }

    public static void main(String[] args) {
        SpringApplication.run(RemoteResourceApplication.class, args);
    }

    //直接请求http://localhost:9009/protect会提示未授权:Full authentication is required to access this resource
    @RequestMapping("/protect")
    public String home(HttpServletRequest req) {
    	System.out.println("url="+req.getRemoteAddr());
        return ">>protect resource!";
    }

    /**
     * 请求http://localhost:9008/oauth/authorize?client_id=admin&redirect_uri=http://localhost:9009/public&response_type=code&scope=read
     * 用户名admin  密码admin  修改用户（authorities, oauth_client_details, users）
     * @param req
     * @return
     */
    @RequestMapping("/public")
    public String home2(HttpServletRequest req) {
    	Enumeration<String> enu=req.getParameterNames();  
    	while(enu.hasMoreElements()){  
	    	String paraName=(String)enu.nextElement();  
	    	System.out.println(paraName+": "+req.getParameter(paraName));
    	}
    	String token = "";//授权token
    	String res = "public resource";//默认返回值

    	//登陆并点击授权获取授权服务器的code
    	String authCode = req.getParameter("code");
    	if(authCode!=null){
    		//根据code换token
    		String getTokenUrl = serverUrl+"/oauth/token?code="+authCode+"&scope="+scope+"&client_id="+username+"&client_secret="+username+"&grant_type=authorization_code&redirect_uri="+clientUrl+publicResource;
    		String tokenJson = HttpUtil.doPost(getTokenUrl);
    		//根据token访问受限资源/hello
    		JsonObject json = new JsonParser().parse(tokenJson).getAsJsonObject();
    		token = (json.get("access_token")+"").replaceAll("\"", "");
    		String getResUrl = clientUrl+authResource+"?token="+token;
    		res = HttpUtil.doPost(getResUrl, null);
    		System.out.println("code=="+authCode+";;scope="+scope+";;token="+token+"__res="+res+";;getResUrl="+getResUrl);
    	}
        return "hello  >>"+res+"!";
    }

    @RequestMapping(value = "/", method = RequestMethod.POST)
    @ResponseStatus(HttpStatus.CREATED)
    public String create(@RequestBody MultiValueMap<String, String> map) {
        return "OK";
    }

    @Override
    public void configure(HttpSecurity http) throws Exception {
        http.authorizeRequests().antMatchers(HttpMethod.GET, authResource).authenticated();
    }

    @Override
    public void configure(ResourceServerSecurityConfigurer resources) throws Exception {
        System.out.println("==========================Configuring ResourceServerSecurityConfigurer ");
        resources.resourceId("oauth2-resource");
    }

}
